home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
DCLAP 6d
/
dclap6d
/
corelib
/
ncbistr.c
< prev
next >
Wrap
Text File
|
1996-07-05
|
12KB
|
470 lines
/* ncbistr.c
* ===========================================================================
*
* PUBLIC DOMAIN NOTICE
* National Center for Biotechnology Information
*
* This software/database is a "United States Government Work" under the
* terms of the United States Copyright Act. It was written as part of
* the author's official duties as a United States Government employee and
* thus cannot be copyrighted. This software/database is freely available
* to the public for use. The National Library of Medicine and the U.S.
* Government have not placed any restriction on its use or reproduction.
*
* Although all reasonable efforts have been taken to ensure the accuracy
* and reliability of the software and data, the NLM and the U.S.
* Government do not and cannot warrant the performance or results that
* may be obtained by using this software or data. The NLM and the U.S.
* Government disclaim all warranties, express or implied, including
* warranties of performance, merchantability or fitness for any particular
* purpose.
*
* Please cite the author in any work or product based on this material.
*
* ===========================================================================
*
* File Name: ncbistr.c
*
* Author: Gish, Kans, Ostell, Schuler
*
* Version Creation Date: 3/4/91
*
* $Revision: 2.4 $
*
* File Description:
* portable string routines
*
* Modifications:
* --------------------------------------------------------------------------
* Date Name Description of modification
* ------- ---------- -----------------------------------------------------
* 3/4/91 Kans Stricter typecasting for GNU C and C++.
* 09-19-91 Schuler Changed all types expressing sizes to size_t.
* 09-19-91 Schuler Changed return type for compare functions to int.
* 09-19-91 Schuler Changed all functions to _cdecl calling convention.
* 09-19-91 Schuler Where possible, NCBI functions call the actual ANSI
* functions after checking for NULL pointers.
* 09-19-91 Schuler Debug-class error posted on any NULL argument.
* 09-19-91 Schuler StringSave() calls MemGet() instead of MemNew().
* 09-19-91 Schuler StringSave(NULL) returns NULL.
* 10-17-91 Schuler Removed ErrPost() calls on NULL arguments.
* 10-17-91 Schuler Added Nlm_StringCnt(),Nlm_StringStr(),Nlm_StringTok()
* 11-18-91 Schuler Added more ANSI-style functions
* 04-15-93 Schuler Changed _cdecl to LIBCALL
* 05-27-93 Schuler Added const qualifiers to match ANSI cognates
*
* ==========================================================================
*/
#include <ncbi.h>
#include <ncbiwin.h>
/* ClearDestString clears the destination string if the source is NULL. */
static Nlm_CharPtr NEAR Nlm_ClearDestString (Nlm_CharPtr to, Nlm_sizeT max)
{
if (to != NULL && max > 0) {
Nlm_MemSet (to, 0, max);
*to = '\0';
}
return to;
}
Nlm_sizeT LIBCALL Nlm_StringLen (const char *str)
{
return str ? StrLen (str) : 0;
}
Nlm_CharPtr LIBCALL Nlm_StringCpy (char FAR *to, const char FAR *from)
{
return (to && from) ? StrCpy (to, from) : Nlm_ClearDestString (to, 1);
}
Nlm_CharPtr LIBCALL Nlm_StringNCpy (char FAR *to, const char FAR *from, Nlm_sizeT max)
{
return (to && from) ? StrNCpy (to, from, max) : Nlm_ClearDestString (to, max);
}
Nlm_CharPtr LIBCALL Nlm_StringCat (char FAR *to, const char FAR *from)
{
return (to && from) ? StrCat (to, from) : to;
}
Nlm_CharPtr LIBCALL Nlm_StringNCat (char FAR *to, const char FAR *from, Nlm_sizeT max)
{
return (to && from) ? StrNCat (to, from, max) : to;
}
int LIBCALL Nlm_StringCmp (const char FAR *a, const char FAR *b)
{
#ifdef DCLAP
/* return a sensible result of one str is NULL, e.g. NULL < anystring */
if (a && b) return StrCmp(a,b);
else if (a) return 1;
else if (b) return -1;
else return 0;
#else
return (a && b) ? StrCmp (a, b) : 0;
#endif
}
int LIBCALL Nlm_StringNCmp (const char FAR *a, const char FAR *b, Nlm_sizeT max)
{
#ifdef DCLAP
if (a && b) return StrNCmp (a, b, max);
else if (a) return 1;
else if (b) return -1;
else return 0;
#else
return (a && b) ? StrNCmp (a, b, max) : 0;
#endif
}
int LIBCALL Nlm_StringICmp (const char FAR *a, const char FAR *b)
{
#ifdef DCLAP
if (a && b) return Nlm_StrICmp (a, b);
else if (a) return 1;
else if (b) return -1;
else return 0;
#else
return (a && b) ? Nlm_StrICmp (a, b) : 0;
#endif
}
int LIBCALL Nlm_StringNICmp (const char FAR *a, const char FAR *b, Nlm_sizeT max)
{
#ifdef DCLAP
if (a && b) return Nlm_StrNICmp (a, b, max);
else if (a) return 1;
else if (b) return -1;
else return 0;
#else
return (a && b) ? Nlm_StrNICmp (a, b, max) : 0;
#endif
}
Nlm_CharPtr LIBCALL Nlm_StringChr (const char FAR *str, int chr)
{
return str ? Nlm_StrChr(str,chr) : NULL;
}
Nlm_CharPtr LIBCALL Nlm_StringRChr (const char FAR *str, int chr)
{
return str ? Nlm_StrRChr(str,chr) : NULL;
}
Nlm_sizeT LIBCALL Nlm_StringSpn (const char FAR *a, const char FAR *b)
{
return (a && b) ? Nlm_StrSpn (a, b) : 0;
}
Nlm_sizeT LIBCALL Nlm_StringCSpn (const char FAR *a, const char FAR *b)
{
return (a && b) ? Nlm_StrCSpn (a, b) : 0;
}
Nlm_CharPtr LIBCALL Nlm_StringPBrk (const char FAR *a, const char FAR *b)
{
return (a && b) ? Nlm_StrPBrk (a, b) : NULL;
}
Nlm_CharPtr LIBCALL Nlm_StringStr (const char FAR *str1, const char FAR *str2)
{
return (str1 && str2) ? Nlm_StrStr(str1,str2) : NULL;
}
Nlm_CharPtr LIBCALL Nlm_StringTok (char FAR *str1, const char FAR *str2)
{
return str2 ? Nlm_StrTok(str1,str2) : NULL;
}
Nlm_CharPtr LIBCALL Nlm_StringMove (char FAR *to, const char FAR *from)
{
return (to && from) ? Nlm_StrMove (to, from) : to;
}
Nlm_CharPtr LIBCALL Nlm_StringSave (const char FAR *from)
{
return from ? Nlm_StrSave (from) : NULL;
}
Nlm_CharPtr LIBCALL Nlm_StringSaveNoNull (const char FAR *from)
{
if (from == NULL) return NULL;
if (*from == '\0') return NULL;
return Nlm_StrSave (from);
}
Nlm_sizeT LIBCALL Nlm_StringCnt (const char FAR *str, const char FAR *list)
{
return (str && list) ? Nlm_StrCnt(str,list) : 0;
}
char * LIBCALL Nlm_StringUpper (char *string)
{
return (string == NULL) ? NULL : Nlm_StrUpper(string);
}
char * LIBCALL Nlm_StringLower (char *string)
{
return (string == NULL) ? NULL : Nlm_StrLower(string);
}
int LIBCALL Nlm_StrICmp (const char FAR *a, const char FAR *b)
{
int diff, done;
if (a == b) return 0;
done = 0;
while (! done)
{
diff = TO_UPPER(*a) - TO_UPPER(*b);
if (diff)
return (Nlm_Int2) diff;
if (*a == '\0')
done = 1;
else
{
a++; b++;
}
}
return 0;
}
int LIBCALL Nlm_StrNICmp (const char FAR *a, const char FAR *b, Nlm_sizeT max)
{
int diff, done;
if (a == b) return 0;
done = 0;
while (! done)
{
diff = TO_UPPER(*a) - TO_UPPER(*b);
if (diff)
return (Nlm_Int2) diff;
if (*a == '\0')
done = 1;
else
{
a++; b++; max--;
if (! max)
done = 1;
}
}
return 0;
}
Nlm_CharPtr LIBCALL Nlm_StrSave (const char FAR *from)
{
Nlm_sizeT len;
Nlm_CharPtr to;
len = Nlm_StringLen(from);
if ((to = (Nlm_CharPtr) Nlm_MemGet(len +1, FALSE)) != NULL) {
Nlm_MemCpy (to, from, len +1);
}
return to;
}
Nlm_CharPtr LIBCALL Nlm_StrMove (char FAR *to, const char FAR *from)
{
while (*from != '\0')
{
*to = *from;
to++; from++;
}
*to = '\0';
return to;
}
Nlm_sizeT LIBCALL Nlm_StrCnt (const char FAR *s, const char FAR *list)
{
Nlm_sizeT cmap[1<<CHAR_BIT];
Nlm_Byte c;
Nlm_sizeT u, cnt;
const Nlm_Byte *bs = (const Nlm_Byte*)s;
const Nlm_Byte *blist = (const Nlm_Byte*)list;
if (s == NULL || list == NULL)
return 0;
for (u = 0; u < DIM(cmap); ++u)
cmap[u] = 0;
while (*blist != '\0')
++cmap[*blist++];
blist = (Nlm_BytePtr)cmap;
cnt = 0;
while ((c = *bs++) != '\0')
cnt += blist[c];
return cnt;
}
#ifndef COMP_MSC
char * LIBCALL Nlm_StrUpper (char *string)
{
register char *p = string;
ASSERT(string != NULL);
while (*p)
{
if (isalpha(*p))
*p = (char)toupper(*p);
++p;
}
return string;
}
#endif
#ifndef COMP_MSC
char * LIBCALL Nlm_StrLower (char *string)
{
register char *p = string;
ASSERT(string != NULL);
while (*p)
{
if (isalpha(*p))
*p = (char)tolower(*p);
++p;
}
return string;
}
#endif
/* -------------------- MeshStringICmp() --------------------------------
* MeshStringICmp compares strings where / takes precedence to space.
*/
Nlm_Int2 LIBCALL Nlm_MeshStringICmp (const char FAR *str1, const char FAR *str2)
{
Nlm_Char ch1, ch2;
if (str1 == NULL)
{
if (str2 == NULL)
return (Nlm_Int2)0;
else
return (Nlm_Int2)1;
}
else if (str2 == NULL)
return (Nlm_Int2)-1;
while ((*str1 >= ' ') && (*str2 >= ' ') && (TO_LOWER(*str1) == TO_LOWER(*str2)))
{
str1++; str2++;
}
ch1 = *str1;
ch2 = *str2;
if ((ch1 < ' ') && (ch2 < ' '))
return (Nlm_Int2)0;
else if (ch1 < ' ')
return (Nlm_Int2)-1;
else if (ch2 < ' ')
return (Nlm_Int2)1;
if (ch1 == '/')
ch1 = '\31';
if (ch2 == '/')
ch2 = '\31';
if (TO_LOWER (ch1) > TO_LOWER (ch2))
return (Nlm_Int2)1;
else if (TO_LOWER (ch1) < TO_LOWER (ch2))
return (Nlm_Int2)(-1);
else
return (Nlm_Int2)0;
}
/*****************************************************************************
*
* LabelCopy (to, from, buflen)
* Copies the string "from" into "to" for up to "buflen" chars
* if "from" is longer than buflen, makes the last character '>'
* always puts one '\0' to terminate the string in to
* to MUST be one character longer than buflen to leave room for the
* last '\0' if from = buflen.
* returns number of characters transferred to "to"
*
*****************************************************************************/
Nlm_Int2 LIBCALL Nlm_LabelCopy (Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Int2 buflen)
{
Nlm_Int2 len;
if ((to == NULL) || (from == NULL) || (buflen < 0)) return 0;
if (buflen == 0) /* this is a sign of multiple writes */
{
*(to-1) = '>';
return 0;
}
len = buflen;
while ((*from != '\0') && (buflen))
{
*to = *from;
from++; to++; buflen--;
}
if (*from != '\0')
{
*(to - 1) = '>';
}
*to = '\0'; /* buffer is bufferlen+1 */
return (len - buflen);
}
void LIBCALL Nlm_LabelCopyNext(Nlm_CharPtr PNTR to, Nlm_CharPtr from, Nlm_Int2 PNTR buflen)
{
Nlm_Int2 diff;
diff = Nlm_LabelCopy(*to, from, *buflen);
*buflen -= diff; *to += diff;
}
/*****************************************************************************
*
* LabelCopyExtra (to, from, buflen, prefix, suffix)
* Copies the string "from" into "to" for up to "buflen" chars
* if all together are longer than buflen, makes the last character '>'
* always puts one '\0' to terminate the string in to
* to MUST be one character longer than buflen to leave room for the
* last '\0' if from = buflen.
* returns number of characters transferred to "to"
*
* if not NULL, puts prefix before from and suffix after from
* both contained within buflen
*
*
*****************************************************************************/
Nlm_Int2 LIBCALL Nlm_LabelCopyExtra (Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Int2 buflen, Nlm_CharPtr prefix, Nlm_CharPtr suffix)
{
Nlm_Int2 len, diff;
if ((to == NULL) || (buflen < 1) || (from == NULL)) return 0;
len = buflen;
diff = Nlm_LabelCopy(to, prefix, buflen);
buflen -= diff; to += diff;
diff = Nlm_LabelCopy(to, from, buflen);
buflen -= diff; to += diff;
diff = Nlm_LabelCopy(to, suffix, buflen);
buflen -= diff;
return (len-buflen);
}